package com.hunttown.mes.manage.controller;

import com.hunttown.mes.common.cache.Cache;
import com.hunttown.mes.common.keys.KeyConstants;
import com.hunttown.mes.manage.cache.ManageRightMenuCacheData;
import com.hunttown.mes.manage.cache.ManageRightRoleCacheData;
import com.hunttown.mes.manage.controller.common.AdminBaseClass;
import com.hunttown.mes.manage.controller.common.ModelService;
import com.hunttown.mes.manage.controller.server.Server;
import com.hunttown.mes.rpc.domain.*;
import com.hunttown.mes.vo.MenuVO;
import com.hunttown.mes.common.utils.CookieUtils;
import com.hunttown.mes.common.utils.FastJsonUtils;
import com.hunttown.mes.common.utils.StringUtils;
import com.hunttown.mes.manage.service.*;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * @title: 首页
 * @author: wangjunfu
 * @date: 2017-07-27
 * @description:
 */
@Controller
public class IndexController {
    private final Logger log = LoggerFactory.getLogger(IndexController.class);

    private final AnalysisConfigParamManageService configParamService;
    private final AnalysisManageManageService manageService;
    private final AnalysisWebsiteParamManageService websiteService;
    private final IotEnterpriseManageRService enterpriseService;
    private final IotEnterpriseManageRelService enterpriseRelService;
    private final ModelService modelService;
    private final TransportDepartmentManageService departmentService;
    private final Cache jedisCache;
    private final Server server;

    /**
     * 顶级菜单的父ID为0
     */
    private static final String MENU_FIRST_LEVEL_PID = "0";

    //登录方式：[/login]帐号密码；[/signin]短信验证码
    @Value("${login.way}")
    private String loginWay;

    @Autowired
    public IndexController(AnalysisConfigParamManageService configParamService, AnalysisManageManageService manageService, AnalysisWebsiteParamManageService websiteService, IotEnterpriseManageRService enterpriseService, IotEnterpriseManageRelService enterpriseRelService, ModelService modelService, TransportDepartmentManageService departmentService, Cache jedisCache, Server server) {
        this.configParamService = configParamService;
        this.manageService = manageService;
        this.websiteService = websiteService;
        this.enterpriseService = enterpriseService;
        this.enterpriseRelService = enterpriseRelService;
        this.modelService = modelService;
        this.departmentService = departmentService;
        this.jedisCache = jedisCache;
        this.server = server;
    }

    //region //新首页

    /**
     * 新首页
     *
     * @param request servlet
     * @param model   model
     * @return vm
     * @throws Exception ex
     */
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String index(HttpServletResponse response, HttpServletRequest request, Model model) throws Exception {

        //region 注册session
        String pin = AdminBaseClass.getPin(request);
        if (pin != null) {
            UsernamePasswordToken token = new UsernamePasswordToken(pin, "");
            SecurityUtils.getSubject().login(token);
        }
        //endregion

        //region 定时获取个人短消息
        AnalysisManageDTO curr_obj = manageService.getFromCachePin(pin);
        int userId = modelService.getUserIdByAdminId(curr_obj.getId());
        model.addAttribute("userId", userId);
        //endregion

        //region 获取小程序扫码地址
        AnalysisConfigParamDTO xcxobj = configParamService.getFromCacheKey("xcx-url");
        if (xcxobj == null || xcxobj.getParamValue().equals("/")) {
            model.addAttribute("xcxUrl", "/static/assets/images/xcx/default.jpg");
        } else {
            model.addAttribute("xcxUrl", xcxobj.getParamValue());
        }
        //endregion

        //region 获取设置中心权限
        //菜单ID：1156
        boolean showSetting = false;
        if (curr_obj.getIsSuper() == 1) {
            showSetting = true;
        } else {
            List<Integer> menuIds = manageService.getMenuIdListByAdminName(pin);
            if (menuIds.contains(1156)) {
                showSetting = true;
            }
        }
        model.addAttribute("showSetting", showSetting);
        //endregion

        //region [0].如果企业ID不存在，则直接跳转到登录页面
        if (jedisCache.get(KeyConstants.WEBSITE_CURRENT_ENTERPRISE_ID + pin).equals("-1")) {
            response.sendRedirect("/logon");
        }
        //endregion

        //region [1].如果来源于登录，则跳转到用户选择企业页面
        String referer = request.getHeader("referer");
        if (referer != null && (referer.contains("/login") || referer.contains("/signin"))) {

            //1-1.获取当前用户所关联的企业
            List<IotEnterpriseManageDTO> enterRelList = enterpriseRelService.getEnterpriseListByManage(curr_obj.getId());

            //1-2.当前用户未关联任务企业，则跳转到无权限
            if (enterRelList == null || enterRelList.size() == 0) {
                return "/help/unauthorized";
            }

            //1-3.如果只关联了一个企业，则直接写缓存
            if (enterRelList.size() == 1) {
                jedisCache.set(KeyConstants.WEBSITE_CURRENT_ENTERPRISE_ID + pin, enterRelList.get(0).getEntId() + "", 180 * 24 * 60 * 60);

            } else {
                //1-4.如果关联了多个企业，则跳转到选择界面
                for (IotEnterpriseManageDTO item : enterRelList) {
                    item.setEntName(enterpriseService.getEnterNameById(item.getEntId()));
                }
                model.addAttribute("enterpriseList", enterRelList);

                //当前企业ID
                int entId = jedisCache.get(KeyConstants.WEBSITE_CURRENT_ENTERPRISE_ID + pin, -1);
                model.addAttribute("currentEntId", entId);

                return "/index-enterprise";
            }
        }
        //endregion

        //region [2].正常跳转
        try {
            //region 1.Topbar
            String nick = AdminBaseClass.getNick(request);
            model.addAttribute("cnName", nick);

            //网站名称
            model.addAttribute("websiteName", websiteService.getWebsiteNameFromCache(request, pin));
            model.addAttribute("websiteFullName", websiteService.getWebsiteFullNameFromCache(request, pin));

            AnalysisManageDTO admindto = manageService.getFromCacheNickname(nick);
            model.addAttribute("headNumer", admindto.getHeadPicNumber());

            //endregion

            //region 2.显示顶部菜单
            //查询用户拥有权限的菜单
            List<AnalysisManageRightMenuDTO> menuDTOS = new ArrayList<>();

            //从 Cookie 中获取用户数据
            //AnalysisManageDTO user = (AnalysisManageDTO) SecurityUtils.getSubject().getSession().getAttribute(KeyConstants.LOGIN_SESSION_ADMIN + pin);
            AnalysisManageDTO user = manageService.getFromCachePin(pin);

            if (user != null && user.getIsSuper() == 1 && user.getCustomizeMenu() == 0) {
                menuDTOS = getAdminMenus(true);
            } else {
                menuDTOS = getUserMenus(pin, true);
            }

            model.addAttribute("frontShowMenu", menuDTOS);
            //endregion

        } catch (Exception e) {
            e.printStackTrace();
        }

        return "/index";

        //endregion
    }
    //endregion

    //region //首页（左侧菜单）

    /**
     * 左侧菜单构建
     *
     * @param model model模型
     * @return vm
     */
    @RequestMapping(value = "/side_menu", method = RequestMethod.GET)
    public String userMenu(HttpServletRequest request, Model model) throws Exception {

        // 从 Cookie 中获取用户数据
        String pin = AdminBaseClass.getPin(request);
        AnalysisManageDTO user = manageService.getFromCachePin(pin);

        List<AnalysisManageRightMenuDTO> menuDTOS = new ArrayList<>();
        if (user == null) {
            return "/side_menu_ace";
        }
        model.addAttribute("isSuper", user.getIsSuper());
        model.addAttribute("customizeMenu", user.getCustomizeMenu());

        //System.out.println("菜单-super：" + user.getIsSuper() + "（" + user.getId() + "）");
        if (user.getIsSuper() == 1 && user.getCustomizeMenu() == 0) {
            menuDTOS = getAdminMenus(false);
        } else {
            menuDTOS = getUserMenus(pin, false);
        }

        //从参数中获取菜单通用分类ID配置
        String rightmenuJson = configParamService.getByParamKey("rightmenu-cateids", "");
        Map<String, Integer> rightMenuMap = new HashMap<>();
        if (StringUtils.isNotBlank(rightmenuJson)) {
            rightMenuMap = FastJsonUtils.fromJSON(rightmenuJson, Map.class);
        }

        if (menuDTOS.size() > 0) {
            //整理菜单上下级关系
            Map<String, List<MenuVO>> menusMap = new HashMap<>();
            for (AnalysisManageRightMenuDTO dto : menuDTOS) {

                //菜单通用分类ID替换
                if (rightMenuMap != null && dto.getMenuPath() != null && dto.getMenuPath().contains("%s")) {
                    dto.setMenuPath(String.format(dto.getMenuPath(), rightMenuMap.get(dto.getMenuNameEn())));
                }

                MenuVO vo = new MenuVO(dto);
                List<MenuVO> templist = menusMap.get(vo.getPid() + "");
                if (templist != null) {
                    templist.add(vo);
                } else {
                    templist = new ArrayList<>();
                    templist.add(vo);
                    menusMap.put(vo.getPid() + "", templist);
                }
            }

            //首先取出顶级菜单 构建菜单树
            List<MenuVO> menus = menusMap.get(MENU_FIRST_LEVEL_PID);
            sortMenus(menus);
            initSubMenus(menus, menusMap);

            model.addAttribute("menus", menus);
        }

        //region // 通过用户部门判断展开那个菜单
        String firt_menu_name = "";
        String second_menu_name = "";

        //员工所属部门逻辑改了，这里不起作用了。
        if (user.getDepId() != null && user.getDepId() > 0) {
            TransportDepartmentDTO departmentDTO = departmentService.getById(user.getDepId());
            if (departmentDTO != null && StringUtils.isNotBlank(departmentDTO.getOpenMune())) {
                String[] openmenu = departmentDTO.getOpenMune().split("\\|");
                firt_menu_name = openmenu[0];

                if (openmenu.length > 1) {
                    second_menu_name = openmenu[1];
                }
            }
        }

        //如果展开菜单为空，则从参数配置中获取默认值
        if (StringUtils.isBlank(firt_menu_name)) {
            String openmenuStr = configParamService.getByParamKey("menu-open", "");
            if (StringUtils.isNotBlank(openmenuStr) && !openmenuStr.equals("|")) {
                String[] openmenu = openmenuStr.split("\\|");
                firt_menu_name = openmenu[0];

                if (openmenu.length > 1) {
                    second_menu_name = openmenu[1];
                }
            }
        }

        model.addAttribute("firtMenuName", firt_menu_name);
        model.addAttribute("secondMenuName", second_menu_name);
        //endregion

        //网站名称
        model.addAttribute("websiteFullName", websiteService.getWebsiteFullNameFromCache(request, pin));

        return "/side_menu_ace";
    }

    /**
     * 获取管理员菜单 目前管理可以查看所有菜单权限
     */
    private List<AnalysisManageRightMenuDTO> getAdminMenus(Boolean isFrontShow) {
        List<AnalysisManageRightMenuDTO> menuDTOS = new ArrayList<>();
        Map<String, AnalysisManageRightMenuDTO> all = ManageRightMenuCacheData.getAllDatas(true);
        if (all != null && all.size() > 0) {
            for (Map.Entry<String, AnalysisManageRightMenuDTO> entry : all.entrySet()) {
                AnalysisManageRightMenuDTO menu = entry.getValue();
                //只显示界面菜单
                if (menu != null && menu.getPathType() != null && menu.getPathType() == 1) {
                    if (isFrontShow) {
                        if (menu.getIsFrontShow() == 1) {
                            menuDTOS.add(menu);
                        }
                    } else {
                        menuDTOS.add(menu);
                    }
                }
            }
        }
        return menuDTOS;
    }

    /**
     * 获取用户权限菜单
     */
    private List<AnalysisManageRightMenuDTO> getUserMenus(String pin, Boolean isFrontShow) {
        List<AnalysisManageRightMenuDTO> menuDTOS = new ArrayList<>();

        //查询用户拥有权限的菜单
        List<Integer> menuIds = manageService.getMenuIdListByAdminName(pin);

        // 需要加一个步骤：需要把每一个id的最顶级id找出来。edit by wangjunfu
        // 因为有时候会只给一个三级菜单的权限
        List<Integer> pList = new ArrayList<>();
        List<Integer> newIds = new ArrayList<>(menuIds);

        for (Integer item : menuIds) {
            pList = ManageRightMenuCacheData.getLastParentId(item);
            for (Integer pId : pList) {
                if (!newIds.contains(pId)) {
                    newIds.add(pId);
                }
            }
        }

        menuIds = newIds;

        for (Integer id : menuIds) {
            AnalysisManageRightMenuDTO menu = ManageRightMenuCacheData.getMenuById(id);
            //只显示界面菜单
            if (menu != null && menu.getPathType() != null && menu.getPathType() == 1) {
                if (isFrontShow) {
                    if (menu.getIsFrontShow() == 1) {
                        menuDTOS.add(menu);
                    }
                } else {
                    menuDTOS.add(menu);
                }
            }
        }

        return menuDTOS;
    }

    /**
     * 根据menus sort属性排序
     */
    private void sortMenus(List<MenuVO> menus) {
        if (menus == null) {
            return;
        }
        menus.sort(new Comparator<MenuVO>() {
            @Override
            public int compare(MenuVO o1, MenuVO o2) {
                return o1.getSort() - o2.getSort();
            }
        });
    }

    /**
     * @param menus    菜单list
     * @param menusMap 菜单对应子菜单集合
     */
    private void initSubMenus(List<MenuVO> menus, Map<String, List<MenuVO>> menusMap) {
        for (MenuVO vo : menus) {
            List<MenuVO> submenus = menusMap.get(vo.getId() + "");
            if (submenus != null && submenus.size() > 0) {
                sortMenus(submenus);
                vo.setSubMenus(submenus);
                initSubMenus(submenus, menusMap);
            }
        }
    }
    //endregion

    //region //通用页面

    // 首页 topbar
    @RequestMapping(value = "/topbar", method = RequestMethod.GET)
    public String topbar(HttpServletRequest request, Model model) throws Exception {
        String nick = AdminBaseClass.getNick(request);
        model.addAttribute("cnName", nick);

        //网站名称
        String pin = AdminBaseClass.getPin(request);
        model.addAttribute("websiteName", websiteService.getWebsiteNameFromCache(request, pin));
        model.addAttribute("websiteFullName", websiteService.getWebsiteFullNameFromCache(request, pin));

        AnalysisManageDTO admindto = manageService.getFromCacheNickname(nick);
        model.addAttribute("headNumer", admindto.getHeadPicNumber());

        return "/topbar";
    }

    // 404 错误
    @RequestMapping(value = "/nopage", method = RequestMethod.GET)
    public String nopage(Model model) {
        return "/help/error404";
    }

    // 500 错误
    @RequestMapping(value = "/error", method = RequestMethod.GET)
    public String error(HttpServletRequest request, Model model) {
        String pin = AdminBaseClass.getPin(request);
        AnalysisManageDTO curr_obj = manageService.getFromCachePin(pin);
        model.addAttribute("isSuper", curr_obj == null ? 0 : curr_obj.getIsSuper());

        return "/help/error500";
    }

    // 无访问权限
    @RequestMapping(value = "/unauthorized", method = RequestMethod.GET)
    public String unauthorized(Model model) {
        return "help/unauthorized";
    }

    // 权限申请
    @RequestMapping(value = "/permissionapply", method = RequestMethod.GET)
    public String permissionApply(Model model) {
        return "help/permissionapply";
    }
    //endregion

    //region //企业选择
    @RequestMapping(value = "/index-enterprise", method = RequestMethod.GET)
    public String indexEnterprise(HttpServletRequest request, Model model) throws Exception {

        String pin = AdminBaseClass.getPin(request);
        AnalysisManageDTO curr_obj = manageService.getFromCachePin(pin);

        //获取当前用户所关联的企业
        List<IotEnterpriseManageDTO> enterList = enterpriseRelService.getEnterpriseListByManage(curr_obj.getId());
        for (IotEnterpriseManageDTO item : enterList) {
            item.setEntName(enterpriseService.getEnterNameById(item.getEntId()));
        }

        model.addAttribute("enterpriseList", enterList);

        //当前企业ID
        int entId = jedisCache.get(KeyConstants.WEBSITE_CURRENT_ENTERPRISE_ID + pin, -1);
        model.addAttribute("currentEntId", entId);

        return "/index-enterprise";
    }

    /**
     * 设置企业ID
     *
     * @param action 企业ID，如果不为空，则进行写缓存
     * @return json
     */
    @RequestMapping(value = "/doEnterprise", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> doEnterprise(HttpServletRequest request, HttpServletResponse response, Integer action) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("returnCode", 0);

        String pin = AdminBaseClass.getPin(request);

        //region [1].如果企业ID不为空，直接写入缓存
        if (action != null && action > 0) {
            AnalysisManageDTO curr_obj = manageService.getFromCachePin(pin);

            //首先判断一下当前用户是否关联这个企业
            List<Integer> enterRelIds = enterpriseRelService.getEnterpriseIdByManage(curr_obj.getId());

            //如果未授权，则直接跳转到无权限
            if (!enterRelIds.contains(action)) {
                return map;
            }

            //企业ID保存半年
            jedisCache.set(KeyConstants.WEBSITE_CURRENT_ENTERPRISE_ID + pin, action + "", 180 * 24 * 60 * 60);

            //切换企业成功后，将“historyPath” 替换为系统信息
            String mainIndex = configParamService.getByParamKey("index-main", "/main-server");
            CookieUtils.setCookie(response, "historyPath", mainIndex, 8 * 60 * 60);
        }
        //endregion

        //region [2].重新写用户session以便切换权限
        AnalysisManageDTO curr_obj = manageService.getFromCachePin(pin);
        ManageRightRoleCacheData.resetUserSession(curr_obj, pin);
        System.out.println("session已切换：" + curr_obj.getIsSuper() + "（" + curr_obj.getId() + "）");
        //endregion

        map.put("returnCode", 1);
        return map;
    }
    //endregion

    //region //登录选择
    @RequestMapping(value = "/logon", method = RequestMethod.GET)
    public void logon(HttpServletResponse response) throws Exception {
        response.sendRedirect(loginWay);
    }

    @RequestMapping(value = "/logonout", method = RequestMethod.GET)
    public void logonout(HttpServletResponse response) throws Exception {
        response.sendRedirect(loginWay + "/logout");
    }
    //endregion

    //region ****** 主页 ******
    @RequestMapping(value = "/main", method = RequestMethod.GET)
    public void main(HttpServletResponse response) throws Exception {
        //从配置中获取首页，如果不存在则给默认值
        String mainIndex = configParamService.getByParamKey("index-main", "/main-server");

        //跳转
        response.sendRedirect(mainIndex);
    }
    //endregion

    //region //主页（服务器信息）
    @RequestMapping(value = "/main-server", method = RequestMethod.GET)
    public String mainServer(HttpServletRequest request, Model model) throws Exception {
        String pin = AdminBaseClass.getPin(request);
        AnalysisManageDTO curr_obj = manageService.getFromCachePin(pin);
        model.addAttribute("adminName", curr_obj.getNickName());
        model.addAttribute("adminId", curr_obj.getId());

        //服务器信息
        server.copyTo();
        model.addAttribute("server", server);

        //网站名称
        model.addAttribute("websiteName", websiteService.getWebsiteNameFromCache(request, pin));

        return "main-server";
    }
    //endregion

}